package com.dshore.messagecenter.util;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;

/**
 * 在线编辑word
 * 针对windows
 * @author panyi-com
 *
 */
public class WordEditUtil {
	
	//针对.doc
	public static boolean getBuild(String  tmpFile, Map<String, String> contentMap, String exportFile){
        InputStream inputStream = WordEditUtil.class.getClassLoader().getResourceAsStream(tmpFile);
        HWPFDocument document = null;
        try {
            document = new HWPFDocument(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 读取文本内容
        Range bodyRange = document.getRange();
        // 替换内容
        for (Map.Entry<String, String> entry : contentMap.entrySet()) {
            bodyRange.replaceText("${" + entry.getKey() + "}", entry.getValue());
        }

        //导出到文件到本地
        try {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            document.write(byteArrayOutputStream);
            OutputStream outputStream = new FileOutputStream(exportFile);
            outputStream.write(byteArrayOutputStream.toByteArray());
            outputStream.close();
            
            //把doc转为pdf
            WordToPdfUtil.word2PDF(exportFile,"G:/abc1.pdf");
            //return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return false;
    }
	
	//针对。docx  无法识别${} 
	public static boolean getBuildx(String  tmpFile, Map<String, String> contentMap, String exportFile){
		try {
			InputStream inputStream = WordEditUtil.class.getClassLoader().getResourceAsStream(tmpFile);
			XWPFDocument document = null;
	        try {
	            document = new XWPFDocument(inputStream);
	        } catch (IOException e) {
	            e.printStackTrace();
	        }
			
			// 替换段落中的指定文字
			Iterator<XWPFParagraph> itPara = document.getParagraphsIterator();
			while (itPara.hasNext()) {
				XWPFParagraph paragraph = (XWPFParagraph) itPara.next();
				List<XWPFRun> runs = paragraph.getRuns();
				for (int i = 0; i < runs.size(); i++) {
					String oneparaString = runs.get(i).getText(runs.get(i).getTextPosition());
					if(oneparaString != null){
						for (Map.Entry<String, String> entry : contentMap.entrySet()) {
							oneparaString = oneparaString.replace(entry.getKey(), entry.getValue());
						}
						runs.get(i).setText(oneparaString, 0);
					}
				}
			}
	
			// 替换表格中的指定文字
			Iterator<XWPFTable> itTable = document.getTablesIterator();
			while (itTable.hasNext()) {
				XWPFTable table = (XWPFTable) itTable.next();
				int rcount = table.getNumberOfRows();
				for (int i = 0; i < rcount; i++) {
					XWPFTableRow row = table.getRow(i);
					List<XWPFTableCell> cells = row.getTableCells();
					for (XWPFTableCell cell : cells) {
						String cellTextString = cell.getText();
						for (Entry<String, String> e : contentMap.entrySet()) {
							if (cellTextString.contains(e.getKey())) {
								cellTextString = cellTextString.replace(e.getKey(),e.getValue());
							}
						}
						cell.removeParagraph(0);
						cell.setText(cellTextString);
					}
				}
			}
				
			FileOutputStream outStream = null;
			outStream = new FileOutputStream(exportFile);
			document.write(outStream);
			outStream.close();
			
			
			//把docx转为pdf
			WordToPdfUtil.word2PDF(exportFile,"G:/abc2.pdf");
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return false;
	} 
	
	//针对。docx  可以识别${} 
	public boolean getBuildY(String  tmpFile, Map<String, Object> contentMap, String exportFile){
		try {
			 InputStream is= WordEditUtil.class.getClassLoader().getResourceAsStream(tmpFile);
			 XWPFDocument docx= new XWPFDocument(is);
			//替换段落里面的变量
		     this.replaceInPara(docx, contentMap);
		     
		     //替换表格里面的变量
		     this.replaceInTable(docx, contentMap);
			 
		     OutputStream os= new FileOutputStream(exportFile);
		     docx.write(os);
		     this.close(os);
		     this.close(is);
		     return true;
		} catch (FileNotFoundException e3) {
			e3.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 * 替换段落里面的变量
	 * @param docx 要替换的文档
	 * @param params 参数
	 */
	 private void replaceInPara(XWPFDocument docx, Map<String, Object> params) {
	    Iterator<XWPFParagraph> iterator = docx.getParagraphsIterator();
	    XWPFParagraph para;
	    while (iterator.hasNext()) {
	       para = iterator.next();
	       this.replaceInPara(para, params);
	    }
	 }
	 
	 private void replaceInPara(XWPFParagraph para, Map<String, Object> params) {
	      List<XWPFRun> runs;
	      Matcher matcher;
	      if (this.matcher(para.getParagraphText()).find()) {
	         runs = para.getRuns();
	         for (int i=0; i<runs.size(); i++) {
	            XWPFRun run = runs.get(i);
	            String runText = run.toString();
	            matcher = this.matcher(runText);
	            if (matcher.find()) {
	                while ((matcher = this.matcher(runText)).find()) {
	                   runText = matcher.replaceFirst(String.valueOf(params.get(matcher.group(1))));
	                }
	                //直接调用XWPFRun的setText()方法设置文本时，在底层会重新创建一个XWPFRun，把文本附加在当前文本后面，
	                //所以我们不能直接设值，需要先删除当前run,然后再自己手动插入一个新的run。
	                para.removeRun(i);
	                para.insertNewRun(i).setText(runText);
	            }
	         }
	      }
	   }
	 
	 /**
	  * 替换表格里面的变量
	  * @param doc 要替换的文档
	  * @param params 参数
	  */
	 private void replaceInTable(XWPFDocument docx, Map<String, Object> params) {
	      Iterator<XWPFTable> iterator = docx.getTablesIterator();
	      XWPFTable table;
	      List<XWPFTableRow> rows;
	      List<XWPFTableCell> cells;
	      List<XWPFParagraph> paras;
	      while (iterator.hasNext()) {
	         table = iterator.next();
	         rows = table.getRows();
	         for (XWPFTableRow row : rows) {
	            cells = row.getTableCells();
	            for (XWPFTableCell cell : cells) {
	                paras = cell.getParagraphs();
	                for (XWPFParagraph para : paras) {
	                   this.replaceInPara(para, params);
	                }
	            }
	         }
	      }
	   }
	 
	 /**
	  * 正则匹配字符串
	  * @param str
	  * @return
	  */
	   private Matcher matcher(String str) {
	      Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
	      Matcher matcher = pattern.matcher(str);
	      return matcher;
	   }
	   
	   /**
	    * 关闭输入流
	    * @param is
	    */
	   private void close(InputStream is) {
	      if (is != null) {
	         try {
	            is.close();
	         } catch (IOException e) {
	            e.printStackTrace();
	         }
	      }
	   }
	   
	   /**
	    * 关闭输出流
	    * @param os
	    */
	   private void close(OutputStream os) {
	      if (os != null) {
	         try {
	            os.close();
	         } catch (IOException e) {
	            e.printStackTrace();
	         }
	      }
	   }
}
